package com.fankui.crowd.handler;

import com.fankui.crowd.api.MySQLRemoteService;
import com.fankui.crowd.api.RedisRemoteService;
import com.fankui.crowd.config.ShortMessageProperties;
import com.fankui.crowd.constant.CrowdConstant;
import com.fankui.crowd.entity.po.MemberPO;
import com.fankui.crowd.entity.vo.MemberLoginVO;
import com.fankui.crowd.entity.vo.MemberVO;
import com.fankui.crowd.util.CrowdUtil;
import com.fankui.crowd.util.ResultEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * ClassName MemberHandler
 * Description TODO
 * Date 2023/8/8 5:59
 *
 * @Author 范奎
 * @Since JDK 11
 */
@Controller
public class MemberHandler {

    @Autowired
    private ShortMessageProperties shortMessageProperties;

    @Autowired
    private RedisRemoteService redisRemoteService;

    @Autowired
    private MySQLRemoteService mySQLRemoteService;

    @ResponseBody
    @RequestMapping("/auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {
        // 1 发送验证码到phoneNum手机
        ResultEntity<String> sendMessageResultEntity = CrowdUtil.sendCodeByShortMessage(shortMessageProperties.getHost(), shortMessageProperties.getPath(), shortMessageProperties.getMethod(), phoneNum, shortMessageProperties.getAppCode(), shortMessageProperties.getSign(), shortMessageProperties.getSkin());
        // 2 判断短信发送结果
        if (ResultEntity.SUCCESS.equals(sendMessageResultEntity.getResult())) {
            // 3 如果发送成功，则将验证码存入Redis
            String code = sendMessageResultEntity.getData();
            String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
            ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 10, TimeUnit.MINUTES);
            if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
                return ResultEntity.successWithoutData();
            } else {
                return saveCodeResultEntity;
            }
        } else {
            return sendMessageResultEntity;
        }
    }

    @RequestMapping("/auth/do/member/register.json")
    public String register(MemberVO memberVO, ModelMap modelMap) {
        // 1 获取用户输入的手机号
        String phoneNum = memberVO.getPhoneNum();
        // 2 拼Redis众存储验证码的Key
        String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
        // 3 从Redis读取Key对应的value
        ResultEntity<String> resultEntity = redisRemoteService.getRedisValueByKeyRemote(key);
        // 4 检查查询操作是否有效
        String result = resultEntity.getResult();
        if (ResultEntity.FAILED.equals(result)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
            return "member-reg";
        }
        String redisCode = resultEntity.getData();
        if (redisCode == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
            return "member-reg";
        }
        // 5 如果从Redis能够查询到value则比较表单和Redis验证码
        String formCode = memberVO.getCode();
        if (!Objects.equals(formCode, redisCode)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            return "member-reg";
        }
        // 6 如果验证码一致，则从Redis中删除
        redisRemoteService.removeRedisKeyRemote(key);
        // 7 执行密码加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String userpswdBeforeEncode = memberVO.getUserpswd();
        String userpswdAfterEncode = passwordEncoder.encode(userpswdBeforeEncode);
        memberVO.setUserpswd(userpswdAfterEncode);
        // 8 执行保存
        MemberPO memberPO = new MemberPO();
        BeanUtils.copyProperties(memberVO, memberPO);
        ResultEntity<String> saveMemberResultEntity = mySQLRemoteService.saveMember(memberPO);
        if (ResultEntity.FAILED.equals(saveMemberResultEntity.getResult())) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveMemberResultEntity.getMessage());
            return "member-reg";
        }
        return "redirect:http://101.132.226.28/auth/member/to/login/page.html";
    }

    @RequestMapping("/auth/member/to/login/page.json")
    public String login(@RequestParam("loginacct") String loginacct, @RequestParam("userpswd") String userpswd, ModelMap modelMap, HttpSession session) {
        // 1 调用远程接口根据登录账号查询MemberPO对象
        ResultEntity<MemberPO> resultEntity = mySQLRemoteService.getMemberPOByLoginAcctRemote(loginacct);
        if (ResultEntity.FAILED.equals(resultEntity.getResult())) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
            return "member-login";
        }
        MemberPO memberPO = resultEntity.getData();
        if (memberPO == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        // 2 比较密码
        String userpswdFromDB = memberPO.getUserpswd();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matchesResult = passwordEncoder.matches(userpswd, userpswdFromDB);
        if (!matchesResult) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "member-login";
        }
        // 3 创建MemberLoginVo对象存入Session域
        MemberLoginVO memberLoginVo = new MemberLoginVO(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER, memberLoginVo);
        return "redirect:http://101.132.226.28/auth/member/to/center/page.html";
    }

    @RequestMapping("/auth/member/logout.json")
    public String logout(HttpSession session) {
        session.invalidate();
        return "redirect:http://101.132.226.28/";
    }
}
